package org.ciallo.simplemusicplayer.data.repository;

import android.app.Application;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Transformations;
import org.ciallo.simplemusicplayer.R;
import org.ciallo.simplemusicplayer.data.AppDatabase;
import org.ciallo.simplemusicplayer.data.dao.PlaylistDao;
import org.ciallo.simplemusicplayer.data.model.Playlist;
import org.ciallo.simplemusicplayer.data.model.PlaylistInfo;
import org.ciallo.simplemusicplayer.data.model.PlaylistSongCrossRef;
import org.ciallo.simplemusicplayer.data.model.Song;
import timber.log.Timber;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * @author Jukomu
 * @Description: 歌单相关数据的仓库类
 * @Package: org.ciallo.simplemusicplayer.data.repository
 * @Project: SimpleMusicPlayer
 * @name: PlaylistRepository
 * @Date: 2025/5/30-01:01
 * @Filename: PlaylistRepository
 */
public class PlaylistRepository {
    private final PlaylistDao playlistDao;
    private final ExecutorService databaseWriteExecutor;
    private final Application application;

    public PlaylistRepository(Application application) {
        this.application = application;
        AppDatabase database = AppDatabase.getDatabase(application);
        playlistDao = database.playlistDao();
        databaseWriteExecutor = AppDatabase.databaseWriteExecutor;
    }

    /**
     * 获取所有歌单的基础信息 (Playlist 实体)。
     * @return LiveData 包装的歌单列表。
     */
    public LiveData<List<Playlist>> getAllPlaylistsFromDb() { // 重命名以区分
        return playlistDao.getAllPlaylists();
    }

    /**
     * 根据查询词获取歌单的基础信息 (Playlist 实体)，或所有歌单。
     * @param queryWithWildcards 搜索查询词（带通配符）。
     * @return LiveData 包装的歌单列表。
     */
    private LiveData<List<Playlist>> getPlaylistsFilteredFromDb(@Nullable String queryWithWildcards) {
        if (queryWithWildcards == null || queryWithWildcards.trim().isEmpty()) {
            return playlistDao.getAllPlaylists();
        } else {
            return playlistDao.getAllPlaylistsOrSearchByName(queryWithWildcards);
        }
    }

    /**
     * 根据查询词获取歌单的显示信息 (PlaylistInfo)，或所有歌单的显示信息。
     * PlaylistInfo 将包含一个默认的占位符封面。
     *
     * @param query 用户输入的原始搜索查询词 (可以为null或空)。
     * @return LiveData 包装的 PlaylistInfo 列表。
     */
    public LiveData<List<PlaylistInfo>> getPlaylistsInfoFilteredOrAll(@Nullable String query) {
        String searchQueryWithWildcards = null;
        if (query != null && !query.trim().isEmpty()) {
            searchQueryWithWildcards = "%" + query.trim() + "%";
        }

        LiveData<List<Playlist>> sourcePlaylists = getPlaylistsFilteredFromDb(searchQueryWithWildcards);

        return Transformations.map(sourcePlaylists, playlists -> {
            if (playlists == null) return new ArrayList<>();
            // 为每个 Playlist 创建 PlaylistInfo，并设置默认封面
            return playlists.stream()
                    .map(playlist -> new PlaylistInfo(
                            playlist.id,
                            playlist.name,
                            playlist.description, // description 来自 Playlist 实体
                            playlist.creationDate,
                            playlist.songCount,
                            // 使用默认占位符封面
                            "android.resource://" + application.getPackageName() + "/" + R.drawable.ic_default_playlist_cover // <--- 默认封面
                    ))
                    .collect(Collectors.toList());
        });
    }


    /**
     * 获取所有歌单信息（包含动态封面），按创建日期降序。
     * @return LiveData 包装的 PlaylistInfo 列表。
     */
    public LiveData<List<PlaylistInfo>> getAllPlaylistsWithInfo() { // 方法名修改
        LiveData<List<PlaylistDao.PlaylistDetailQueryResult>> rawData = playlistDao.getAllPlaylistsWithFirstSongCover();

        return Transformations.map(rawData, queryResults -> {
            if (queryResults == null) {
                return Collections.emptyList();
            }
            List<PlaylistInfo> playlistInfoList = new ArrayList<>();
            for (PlaylistDao.PlaylistDetailQueryResult result : queryResults) {
                // 如果 firstSongCoverUri 为 null，则使用默认歌单封面
                String displayCover = result.firstSongCoverUri;
                // 你可以定义一个 R.drawable.default_playlist_cover
                // if (displayCover == null) {
                //    displayCover = "android.resource://" + application.getPackageName() + "/" + R.drawable.default_playlist_cover;
                // }
                // PlaylistGridAdapter 中也会处理null封面显示默认图，所以这里可以直接传递null

                playlistInfoList.add(new PlaylistInfo(
                        result.id,
                        result.name,
                        result.description,
                        result.creationDate,
                        result.songCount,
                        displayCover // 这个可能是 null
                ));
            }
            return playlistInfoList;
        });
    }

    /**
     * 根据ID获取歌单。
     * @param playlistId 歌单ID。
     * @return LiveData 包装的歌单。
     */
    public LiveData<Playlist> getPlaylistById(long playlistId) { return playlistDao.getPlaylistById(playlistId); }

    /**
     * 获取指定歌单中的所有歌曲，按顺序排列。
     * @param playlistId 歌单ID。
     * @return LiveData 包装的歌曲列表。
     */
    public LiveData<List<Song>> getSongsForPlaylistOrdered(long playlistId) {
        return playlistDao.getSongsForPlaylistOrdered(playlistId);
    }

    /**
     * 创建一个新的歌单。
     * @param name        歌单名称。
     * @param description 歌单描述 (可选)。
     * @return Future 包装的新创建歌单的ID。
     */
    public Future<Long> createPlaylist(final String name, @Nullable final String description) {
        return databaseWriteExecutor.submit(() -> {
            // Playlist 构造函数已更新，不再接收 coverArtUri
            Playlist playlist = new Playlist(name, description, System.currentTimeMillis());
            long newPlaylistId = playlistDao.insertPlaylist(playlist);
            Timber.d("Playlist created with ID: %d, Name: %s", newPlaylistId, name);
            return newPlaylistId;
        });
    }

    /**
     * 更新歌单信息。
     * @param playlist 要更新的歌单对象。
     */
    public void updatePlaylist(final Playlist playlist) {
        databaseWriteExecutor.execute(() -> {
            playlistDao.updatePlaylist(playlist);
            Timber.d("Playlist updated: %s", playlist.getName());
        });
    }

    /**
     * 更新歌单信息。
     * @param playlist 要更新的歌单对象。
     */
    public void updatePlaylist(final PlaylistInfo playlist) {
        databaseWriteExecutor.execute(() -> {
            Playlist playlist1 = new Playlist();
            playlist1.id = playlist.id;
            playlist1.name = playlist.name;
            playlist1.description = playlist.description;
            playlist1.creationDate = playlist.creationDate;
            playlist1.songCount = playlist.songCount;
            playlistDao.updatePlaylist(playlist1);
            Timber.d("Playlist updated: %s", playlist.getName());
        });
    }

    /**
     * 删除歌单。
     * @param playlist 要删除的歌单对象。
     */
    public void deletePlaylist(final Playlist playlist) {
        databaseWriteExecutor.execute(() -> {
            playlistDao.deletePlaylist(playlist);
            Timber.d("Playlist deleted: %s (ID: %d)", playlist.getName(), playlist.getId());
        });
    }

    /**
     * 删除歌单。
     * @param playlist 要删除的歌单对象。
     */
    public void deletePlaylist(final PlaylistInfo playlist) {
        databaseWriteExecutor.execute(() -> {
            Playlist playlist1 = new Playlist();
            playlist1.id = playlist.id;
            playlist1.name = playlist.name;
            playlist1.description = playlist.description;
            playlist1.creationDate = playlist.creationDate;
            playlist1.songCount = playlist.songCount;
            playlistDao.deletePlaylist(playlist1);
            Timber.d("Playlist deleted: %s (ID: %d)", playlist.getName(), playlist.getId());
        });
    }

    /**
     * 将歌曲添加到歌单。
     * @param playlistId 歌单ID。
     * @param songId     歌曲ID。
     */
    public void addSongToPlaylist(final long playlistId, final long songId) {
        databaseWriteExecutor.execute(() -> {
            int position = playlistDao.getNextPositionInPlaylist(playlistId);
            PlaylistSongCrossRef crossRef = new PlaylistSongCrossRef(playlistId, songId, position);
            playlistDao.addSongToPlaylist(crossRef);
            playlistDao.updatePlaylistSongCountAfterModification(playlistId);
            Timber.d("Song ID %d added to playlist ID %d at position %d", songId, playlistId, position);
        });
    }
    /**
     * 从歌单中移除歌曲。
     * @param playlistId 歌单ID。
     * @param songId     歌曲ID。
     */
    public void removeSongFromPlaylist(final long playlistId, final long songId) {
        databaseWriteExecutor.execute(() -> {
            playlistDao.removeSongFromPlaylist(playlistId, songId);
            playlistDao.updatePlaylistSongCountAfterModification(playlistId);
            Timber.d("Song ID %d removed from playlist ID %d", songId, playlistId);
        });
    }

    /**
     * 获取所有歌单。
     * (这个方法保持不变，用于无搜索条件时)
     * @return LiveData 包装的歌单列表。
     */
    public LiveData<List<Playlist>> getAllPlaylists() {
        return playlistDao.getAllPlaylists();
    }

    /**
     * 根据查询词获取歌单列表 (如果查询词为空，则获取所有歌单)，按创建日期降序。
     *
     * @param query 用户输入的原始搜索查询词 (可以为null或空)。
     * @return LiveData 包装的匹配或所有歌单列表。
     */
    public LiveData<List<Playlist>> getPlaylistsFilteredOrAll(@Nullable String query) {
        if (query == null || query.trim().isEmpty()) {
            // 如果没有搜索词，返回所有歌单
            return playlistDao.getAllPlaylists(); // 或者调用 playlistDao.getAllPlaylistsOrSearchByName(null);
        } else {
            // 如果有搜索词，为其添加通配符并进行搜索
            String searchQueryWithWildcards = "%" + query.trim() + "%";
            return playlistDao.getAllPlaylistsOrSearchByName(searchQueryWithWildcards);
        }
    }
}
